package com.izkml.mlyun.hotreload.service;

import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.StrUtil;
import com.izkml.mlyun.hotreload.constant.Const;
import com.izkml.mlyun.hotreload.enums.ManageCmdEnums;
import com.izkml.mlyun.hotreload.enums.OtherCmdEnums;
import com.izkml.mlyun.hotreload.enums.StatusEnums;
import com.izkml.mlyun.hotreload.model.CallBack;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Slf4j
@Service
public class ManageService {

    @Resource
    private CallBackService callBackService;

    /**
     * 管理命令执行 1
     * 1. start
     * 2. restart
     * 3. reload
     */
    public boolean exec(ManageCmdEnums manageCmd, CallBack callBack) {
        boolean noErr = StrUtil.isEmpty(doExec(manageCmd.getCode()));
        // 异步健康检查，并执行回调逻辑
        if (noErr) {
            callBackService.callBack(callBack);
        }
        return noErr;
    }

    /**
     * 管理命令执行 2
     * 4. stop
     */
    public boolean exec(ManageCmdEnums manageCmd) {
        return StrUtil.isEmpty(doExec(manageCmd.getCode()));
    }

    /**
     * 先检查 maven 进程存在情况
     * 1. 不存在，则为 STOPPED
     * 2. 存在，进一步检查业务 jvm 进程存在情况
     * * 2.1. 不存在，则为 STARTING
     * * 2.2. 存在，进一步检查 mvn compile 进程存在情况
     * * * 2.2.1. 不存在，进一步检查 TCP 监听存在情况
     * * * 2.2.1.1. 存在，则为 RUNNING
     * * * 2.2.1.2. 不存在，则为 STARTING
     * * * 2.2.2. 存在，则为 UPDATING
     */
    public String status() {
        // 检查 maven 进程
        OtherCmdEnums checkCmd = OtherCmdEnums.maven_check;
        String result = doExec(checkCmd.getCode());
        if (StrUtil.isEmpty(result)) {
            return StatusEnums.STOPPED.getCode();
        }
        // 检查业务 jvm 进程
        checkCmd = OtherCmdEnums.app_jvm_check;
        result = doExec(checkCmd.getCode());
        if (StrUtil.isEmpty(result)) {
            return StatusEnums.STARTING.getCode();
        }
        // 检查 mvn compile 进程
        checkCmd = OtherCmdEnums.mvn_compile_check;
        result = doExec(checkCmd.getCode());
        if (StrUtil.isEmpty(result)) {
            // 检查业务 tcp 监听
            checkCmd = OtherCmdEnums.app_tcp_check;
            result = doExec(checkCmd.getCode());
            if (StrUtil.isEmpty(result)) {
                return StatusEnums.STARTING.getCode();
            }
            return StatusEnums.RUNNING.getCode();
        }
        return StatusEnums.UPDATING.getCode();
    }

    /**
     * 校验是否正在生成 openApi
     *
     * @return true正在/false不在
     */
    public boolean testing() {
        // 检查 mvn test 进程
        OtherCmdEnums checkCmd = OtherCmdEnums.mvn_test_check;
        String result = doExec(checkCmd.getCode());
        return StrUtil.isNotEmpty(result);
    }

    /**
     * 读取业务最新 100 行日志
     */
    public void tail100AppLog() {
        OtherCmdEnums checkCmd = OtherCmdEnums.tail_100_app_log;
        doExec(checkCmd.getCode());
    }

    private String doExec(String cmdStr) {
        Process exec = RuntimeUtil.exec(Const.CTL.HELPER_SH, cmdStr);
        String result = RuntimeUtil.getResult(exec);
        log.info("Exec cmd: [{} {}], stdout: {}", Const.CTL.HELPER_SH, cmdStr, StrUtil.isBlank(result) ? "" : result);
        return result;
    }
}
